import { Request, Response } from 'express';
import oauthService from '@/service/oauthService';
import logger from '@/utils/logger';
import { ResponseUtil } from '@/utils/R';

export class OAuthController {

  /**
   * 初始化OAuth控制器
   */
  async initialize(): Promise<void> {
    try {
      await oauthService.initialize();
      logger.info('OAuth控制器初始化成功');
    } catch (error) {
      logger.error('OAuth控制器初始化失败:', error);
      throw error;
    }
  }

  /**
   * 生成OAuth授权URL
   */
  generateAuthUrl = async (req: Request, res: Response) => {
    try {
      const { provider } = req.params;
      const { action = 'login', userId } = req.query;

      const authUrl = await oauthService.generateAuthUrl(
        provider,
        action as string,
        userId as string
      );

      ResponseUtil.success(res, { authUrl }, '生成授权URL成功');
    } catch (error) {
      logger.error('生成OAuth授权URL失败:', error);
      ResponseUtil.internalError(res, error instanceof Error ? error.message : '生成授权URL失败');
    }
  };

  /**
   * 处理OAuth回调
   */
  handleCallback = async (req: Request, res: Response) => {
    try {
      const { provider } = req.params;
      const { code, state, error } = req.query;

      // 获取前端URL，提供默认值
      const frontendUrl = process.env.SITE_DOMAIN;

      // 检查OAuth授权错误
      if (error) {
        logger.error(`OAuth ${provider} 授权失败: ${error}`);
        return res.redirect(`${frontendUrl}/auth/error?message=oauth_error`);
      }

      // 检查必需参数
      if (!code || !state) {
        return res.redirect(`${frontendUrl}/auth/error?message=missing_params`);
      }

      // 调用服务处理回调
      const result = await oauthService.handleCallback(
        provider,
        code as string,
        state as string
      );

      // 重定向到前端
      res.redirect(result.redirectUrl);
    } catch (error) {
      logger.error(`OAuth ${req.params.provider} 回调处理失败:`, error);

      // 获取前端URL，提供默认值
      const frontendUrl = process.env.SITE_DOMAIN;

      // 根据错误类型生成不同的错误消息
      let errorMessage = 'callback_error';
      if (error instanceof Error) {
        if (error.message.includes('状态参数')) {
          errorMessage = 'invalid_state';
        } else if (error.message.includes('过期')) {
          errorMessage = 'state_expired';
        } else if (error.message.includes('不匹配')) {
          errorMessage = 'provider_mismatch';
        } else if (error.message.includes('Network error')) {
          errorMessage = 'network_error';
        } else if (error.message.includes('token exchange failed')) {
          errorMessage = 'token_exchange_failed';
        }
      }

      res.redirect(`${frontendUrl}/auth/error?message=${errorMessage}`);
    }
  };

  /**
   * 获取用户的OAuth账户列表
   */
  getUserAccounts = async (req: Request, res: Response) => {
    try {
      const userId = (req as any).user.id;

      const accounts = await oauthService.getUserOAuthAccounts(userId);

      ResponseUtil.success(res, { accounts }, '获取账户列表成功');
    } catch (error) {
      logger.error('获取用户OAuth账户失败:', error);
      ResponseUtil.internalError(res, error instanceof Error ? error.message : '获取账户列表失败');
    }
  };

  /**
   * 解绑OAuth账户
   */
  unlinkAccount = async (req: Request, res: Response) => {
    try {
      const userId = (req as any).user.id;
      const { provider } = req.params;

      await oauthService.unlinkOAuthAccount(userId, provider);

      ResponseUtil.success(res, null, 'OAuth账户解绑成功');
    } catch (error) {
      logger.error('解绑OAuth账户失败:', error);

      if (error instanceof Error && error.message.includes('未找到')) {
        ResponseUtil.notFound(res, error.message);
      } else {
        ResponseUtil.internalError(res, error instanceof Error ? error.message : '解绑账户失败');
      }
    }
  };

  /**
   * 绑定OAuth账户到现有用户
   */
  linkAccount = async (req: Request, res: Response) => {
    try {
      const userId = (req as any).user.id;
      const { provider } = req.params;
      const { code, state } = req.query;

      if (!code || !state) {
        ResponseUtil.badRequest(res, '缺少必需参数');
        return;
      }

      await oauthService.linkOAuthAccount(
        userId,
        provider,
        code as string,
        state as string
      );

      ResponseUtil.success(res, null, 'OAuth账户绑定成功');
    } catch (error) {
      logger.error('绑定OAuth账户失败:', error);
      ResponseUtil.internalError(res, error instanceof Error ? error.message : '绑定账户失败');
    }
  };
}

export default new OAuthController(); 